﻿#include <CXXLTHREAD.HPP>
#include <SMART_PTR.HPP>

using namespace CxxlMan;

#if (SysSelect == _WIN32_CxxlMan)

#include <windows.h>
#include <process.h>

static unsigned __stdcall ThreadMain(void *arg)
{
  Smart_Ptr<IcxxlThread> *pIcxxlThread_Ptr = (Smart_Ptr<IcxxlThread> *)arg;

  (*pIcxxlThread_Ptr)->ThreadStart();

  delete pIcxxlThread_Ptr;

  return 0;
}

// 負責讓 IcxxlThread 在另一個執行緒中執行，成功回傳 true
CXXL_DLLEXPORT bool cxxlFASTCALL CxxlMan::Thread_Create(const Smart_Ptr<IcxxlThread> &IcxxlThread_Arg)
{
  HANDLE hThreads;
  unsigned threadId;

  Smart_Ptr<IcxxlThread> *pIcxxlThread_Ptr = new Smart_Ptr<IcxxlThread>(IcxxlThread_Arg);

  hThreads = (HANDLE)_beginthreadex(
               NULL,                 /* Thread security */
               0,                    /* Thread stack size */
               ThreadMain,           /* Thread starting address */
               (void *)pIcxxlThread_Ptr,  /* Thread start argument */
               0,                    /* Runs immediately after creation */
               &threadId);

  if(hThreads == INVALID_HANDLE_VALUE)
  {
    delete pIcxxlThread_Ptr;
    return false;
  }
  else
  {
    CloseHandle(hThreads);
    return true;
  }
}


#elif (SysSelect == _LINUX_CxxlMan)

#include <pthread.h>

static void *ThreadMain(void *arg)
{
  Smart_Ptr<IcxxlThread> *pIcxxlThread_Ptr = (Smart_Ptr<IcxxlThread> *)arg;

  (*pIcxxlThread_Ptr)->ThreadStart();

  delete pIcxxlThread_Ptr;

  return 0;
}

// 負責讓 IcxxlThread 在另一個執行緒中執行，成功回傳 true
CXXL_DLLEXPORT bool cxxlFASTCALL CxxlMan::Thread_Create(const Smart_Ptr<IcxxlThread> &IcxxlThread_Arg)
{
  pthread_t ThreadID;

  Smart_Ptr<IcxxlThread> *pIcxxlThread_Ptr = new Smart_Ptr<IcxxlThread>(IcxxlThread_Arg);

  if(pthread_create( &ThreadID, pthread_attr_default, ThreadMain,(void *)pIcxxlThread_Ptr) == -1)
  {
    delete pIcxxlThread_Ptr;
    return false;
  }
  else
  {
    pthread_detach(ThreadID);
    return true;
  }
}

#else
  #error 尚未支援此作業系統
#endif
